package com.oanda.blackberry.restapi;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.microedition.io.HttpsConnection;

import net.rim.device.api.util.Persistable;

import com.oanda.blackberry.net.ConnectionManager;
import com.oanda.blackberry.net.RestException;
import com.oanda.blackberry.net.UrlEncoder;
import com.oanda.blackberry.util.log.Logger;

public class Rate extends Rest implements Persistable {
    Symbol[] symbols;
    Quote[] quotes;
    Quote[] allQuotes;
    PricePoint[] pricePoints;
    static long since = 0L;

    long sinceAll = 0L;

    public String listSymbols(String sessionToken) throws RestException {
        HttpsConnection connection = null;
        InputStream inputstream = null;
        OutputStream outputstream = null;
        if (ConnectionManager.getUrl().equals("device")) {
            return "{\"symbols\":[{\"symbol\":\"EUR/USD\",\"precision\":5,\"piploc\":0.0001},{\"symbol\":\"USD/CAD\",\"precision\":5,\"piploc\":0.0001},{\"symbol\":\"XAU/USD\",\"precision\":3,\"piploc\":0.01}]}";
        }

        String url = ConnectionManager.getUrl() + "v1/rate/list_symbols.json";
        try {
            String parameters = "?session_token=" + UrlEncoder.encode(sessionToken, "");
            url = url + parameters;
        } catch (IOException e) {
        }
        url = url + ConnectionManager.getConnectionSuffix();

        this.response = proceedConnection(url);

        if (this.error) {
            throw new RestException(this.errorMessage
                    + (this.response == null ? "" : this.response));
        }
        Logger.log("rate list symbol response: " + this.response);
        return this.response;
    }

    public String quote(String sessionToken, String symbols, String since) throws RestException {
        if (ConnectionManager.getUrl().equals("device")) {
            return "{\"prices\":[{\"time\":1234567890,\"symbol\":\"EUR/USD\",\"bid\":1.23456,\"ask\":1.23457},{\"time\":1234567890,\"symbol\":\"USD/CAD\",\"bid\":1.11111,\"ask\":1.99999},{\"time\":1234567890,\"symbol\":\"XAU/USD\",\"bid\":1.230,\"ask\":1.299}],\"symbol\":\"USD/JPY\"}";
        }

        String url = ConnectionManager.getUrl() + "v1/rate/quote.json";
        try {
            String parameters = "?session_token=" + UrlEncoder.encode(sessionToken, "")
                    + (symbols != null ? "&symbols=" + UrlEncoder.encode(symbols, "") : "")
                    + (since != null ? "&since=" + UrlEncoder.encode(since, "") : "");

            url = url + parameters;
        } catch (IOException e) {
        }
        url = url + ConnectionManager.getConnectionSuffix();

        this.response = proceedConnection(url);

        if (this.error) {
            throw new RestException("AAAA" + this.errorMessage
                    + (this.response == null ? "" : this.response));
        }
        Logger.log("rate quote response: " + this.response);
        return this.response;
    }

    public byte[] history(String sessionToken, String symbol, int granularity, int points)
            throws RestException {
        if (ConnectionManager.getUrl().equals("device")) {
            return "{\"symbol\":\"EUR/USD\",\"price_points\":[{\"time\":1272441690,\"open_bid\":1.31829,\"open_ask\":1.31838,\"close_bid\":1.31816,\"close_ask\":1.31825,\"max_bid\":1.31829,\"max_ask\":1.31838,\"min_bid\":1.31814,\"min_ask\":1.31823,\"unstable\":false},{\"time\":1272441720,\"open_bid\":1.31816,\"open_ask\":1.31825,\"close_bid\":1.31782,\"close_ask\":1.31791,\"max_bid\":1.31821,\"max_ask\":1.3183,\"min_bid\":1.31781,\"min_ask\":1.3179,\"unstable\":false},{\"time\":1272441750,\"open_bid\":1.31782,\"open_ask\":1.31791,\"close_bid\":1.31778,\"close_ask\":1.31787,\"max_bid\":1.31807,\"max_ask\":1.31816,\"min_bid\":1.31774,\"min_ask\":1.31783,\"unstable\":false},{\"time\":1272441780,\"open_bid\":1.31778,\"open_ask\":1.31787,\"close_bid\":1.31808,\"close_ask\":1.31817,\"max_bid\":1.31808,\"max_ask\":1.31817,\"min_bid\":1.31774,\"min_ask\":1.31783,\"unstable\":false},{\"time\":1272441810,\"open_bid\":1.31808,\"open_ask\":1.31817,\"close_bid\":1.31801,\"close_ask\":1.3181,\"max_bid\":1.31817,\"max_ask\":1.31826,\"min_bid\":1.31801,\"min_ask\":1.3181,\"unstable\":false},{\"time\":1272441840,\"open_bid\":1.31801,\"open_ask\":1.3181,\"close_bid\":1.31814,\"close_ask\":1.31823,\"max_bid\":1.31819,\"max_ask\":1.31828,\"min_bid\":1.31794,\"min_ask\":1.31803,\"unstable\":false},{\"time\":1272441870,\"open_bid\":1.31814,\"open_ask\":1.31823,\"close_bid\":1.31821,\"close_ask\":1.3183,\"max_bid\":1.31824,\"max_ask\":1.31833,\"min_bid\":1.31814,\"min_ask\":1.31823,\"unstable\":false},{\"time\":1272441900,\"open_bid\":1.31821,\"open_ask\":1.3183,\"close_bid\":1.31781,\"close_ask\":1.3179,\"max_bid\":1.31821,\"max_ask\":1.3183,\"min_bid\":1.31781,\"min_ask\":1.3179,\"unstable\":false},{\"time\":1272441930,\"open_bid\":1.31781,\"open_ask\":1.3179,\"close_bid\":1.31793,\"close_ask\":1.31802,\"max_bid\":1.31802,\"max_ask\":1.31811,\"min_bid\":1.31781,\"min_ask\":1.3179,\"unstable\":false}]}"
                    .getBytes();
        }
        String url = ConnectionManager.getUrl() + "v1/rate/history.json";
        try {
            String parameters = "?session_token=" + UrlEncoder.encode(sessionToken, "")
                    + "&symbol=" + UrlEncoder.encode(symbol, "") + "&granularity="
                    + UrlEncoder.encode(String.valueOf(granularity), "") + "&points="
                    + UrlEncoder.encode(String.valueOf(points), "");

            url = url + parameters;
        } catch (IOException e) {
        }
        url = url + ConnectionManager.getConnectionSuffix();

        Object o = proceedConnectionToByteArray(url);
        if ((o instanceof byte[])) {
            return (byte[]) (byte[]) o;
        }

        if (this.error) {
            throw new RestException(this.errorMessage
                    + (this.response == null ? "" : this.response));
        }

        return this.response.getBytes();
    }

    public String historyUpdate(String sessionToken, String symbol, int granularity, int points)
            throws RestException {
        if (ConnectionManager.getUrl().equals("device")) {
            return "{\"symbol\":\"EUR/USD\",\"price_points\":[{\"time\":1272441690,\"open_bid\":1.31829,\"open_ask\":1.31838,\"close_bid\":1.31816,\"close_ask\":1.31825,\"max_bid\":1.31829,\"max_ask\":1.31838,\"min_bid\":1.31814,\"min_ask\":1.31823,\"unstable\":false},{\"time\":1272441720,\"open_bid\":1.31816,\"open_ask\":1.31825,\"close_bid\":1.31782,\"close_ask\":1.31791,\"max_bid\":1.31821,\"max_ask\":1.3183,\"min_bid\":1.31781,\"min_ask\":1.3179,\"unstable\":false},{\"time\":1272441750,\"open_bid\":1.31782,\"open_ask\":1.31791,\"close_bid\":1.31778,\"close_ask\":1.31787,\"max_bid\":1.31807,\"max_ask\":1.31816,\"min_bid\":1.31774,\"min_ask\":1.31783,\"unstable\":false},{\"time\":1272441780,\"open_bid\":1.31778,\"open_ask\":1.31787,\"close_bid\":1.31808,\"close_ask\":1.31817,\"max_bid\":1.31808,\"max_ask\":1.31817,\"min_bid\":1.31774,\"min_ask\":1.31783,\"unstable\":false},{\"time\":1272441810,\"open_bid\":1.31808,\"open_ask\":1.31817,\"close_bid\":1.31801,\"close_ask\":1.3181,\"max_bid\":1.31817,\"max_ask\":1.31826,\"min_bid\":1.31801,\"min_ask\":1.3181,\"unstable\":false},{\"time\":1272441840,\"open_bid\":1.31801,\"open_ask\":1.3181,\"close_bid\":1.31814,\"close_ask\":1.31823,\"max_bid\":1.31819,\"max_ask\":1.31828,\"min_bid\":1.31794,\"min_ask\":1.31803,\"unstable\":false},{\"time\":1272441870,\"open_bid\":1.31814,\"open_ask\":1.31823,\"close_bid\":1.31821,\"close_ask\":1.3183,\"max_bid\":1.31824,\"max_ask\":1.31833,\"min_bid\":1.31814,\"min_ask\":1.31823,\"unstable\":false},{\"time\":1272441900,\"open_bid\":1.31821,\"open_ask\":1.3183,\"close_bid\":1.31781,\"close_ask\":1.3179,\"max_bid\":1.31821,\"max_ask\":1.3183,\"min_bid\":1.31781,\"min_ask\":1.3179,\"unstable\":false},{\"time\":1272441930,\"open_bid\":1.31781,\"open_ask\":1.3179,\"close_bid\":1.31793,\"close_ask\":1.31802,\"max_bid\":1.31802,\"max_ask\":1.31811,\"min_bid\":1.31781,\"min_ask\":1.3179,\"unstable\":false}]}";
        }
        String url = ConnectionManager.getUrl() + "v1/rate/history.json";
        try {
            String parameters = "?session_token=" + UrlEncoder.encode(sessionToken, "")
                    + "&symbol=" + UrlEncoder.encode(symbol, "") + "&granularity="
                    + UrlEncoder.encode(String.valueOf(granularity), "") + "&points="
                    + UrlEncoder.encode(String.valueOf(points), "");

            url = url + parameters;
        } catch (IOException e) {
        }
        url = url + ConnectionManager.getConnectionSuffix();

        this.response = proceedConnection(url);

        if (this.error) {
            throw new RestException(this.errorMessage
                    + (this.response == null ? "" : this.response));
        }

        return this.response;
    }

    public Symbol[] getSymbols() {
        return this.symbols;
    }

    public void setSymbols(Symbol[] symbols) {
        this.symbols = symbols;
    }

    public Quote[] getQuotes() {
        return this.quotes;
    }

    private void updateQuotes(Quote[] quotes) {
        for (int i = 0; i < quotes.length; i++) {
            Quote quote = quotes[i];
            for (int j = 0; j < this.quotes.length; j++) {
                Quote quote1 = this.quotes[j];
                if ((!quote.getSymbol().equals(quote1.getSymbol())) || (quote.equals(quote1))) {
                    continue;
                }
                this.quotes[j] = quote;
            }
        }
    }

    public void clearQuotes() {
        this.quotes = null;
    }

    public void setQuotes(Quote[] quotes) {
        if (since == 0L) {
            this.quotes = quotes;
            return;
        }

        if (this.quotes != null)
            updateQuotes(quotes);
        else
            this.quotes = quotes;
    }

    public Quote[] getQuotesAll() {
        return this.allQuotes;
    }

    private void updateQuotesAll(Quote[] quotesAll) {
        for (int i = 0; i < quotesAll.length; i++) {
            Quote quote = quotesAll[i];
            for (int j = 0; j < this.allQuotes.length; j++) {
                Quote quote1 = this.allQuotes[j];
                if ((!quote.getSymbol().equals(quote1.getSymbol())) || (quote.equals(quote1))) {
                    continue;
                }
                this.allQuotes[j] = quote;
            }
        }
    }

    public void setQuotesAll(Quote[] quotesAll) {
        if ((this.allQuotes != null) && (quotesAll != null))
            updateQuotesAll(quotesAll);
        else
            this.allQuotes = quotesAll;
    }

    public Quote getQuote(String symbolName) {
        if (this.quotes == null)
            return null;
        for (int i = 0; i < this.quotes.length; i++) {
            if (this.quotes[i].getSymbol().equals(symbolName)) {
                return this.quotes[i];
            }
        }

        return null;
    }

    public Quote getQuoteFromAll(String symbolName) {
        if (this.allQuotes == null)
            return null;
        for (int i = 0; i < this.allQuotes.length; i++) {
            if (this.allQuotes[i].getSymbol().equals(symbolName)) {
                return this.allQuotes[i];
            }
        }

        return null;
    }

    public Symbol getSymbol(String symbolName) {
        for (int i = 0; (this.symbols != null) && (i < this.symbols.length); i++) {
            if (this.symbols[i].getSymbol().equals(symbolName)) {
                return this.symbols[i];
            }
        }

        return null;
    }

    public static boolean isQuotesEquals(Quote[] q1, Quote[] q2) {
        if (q1.length != q2.length) {
            return false;
        }

        for (int i = 0; i < q1.length; i++) {
            if (!q1[i].getSymbol().equals(q2[i].getSymbol())) {
                return false;
            }
        }
        return true;
    }

    public static boolean isQuotesEquals(Quote q1, Quote q2) {
        if ((q1 == null) && (q2 == null)) {
            return true;
        }

        if ((q1 == null) || (q2 == null)) {
            return false;
        }

        if ((q1 != null) && (q2 != null)) {
            return q1.equals(q2);
        }
        return false;
    }

    public void setPricePoints(PricePoint[] pricePoints) {
        this.pricePoints = pricePoints;
    }

    public PricePoint[] getPricePoints() {
        return this.pricePoints;
    }

    public static void setSince(long sinceT) {
        since = sinceT;
    }

    public static long getSince() {
        return since;
    }

    public void setSinceAll(long sinceAll) {
        this.sinceAll = sinceAll;
    }

    public long getSinceAll() {
        return this.sinceAll;
    }

    public void sortSymbols() {
        if ((this.symbols != null) && (this.symbols.length > 0)) {
            Symbol temp = null;
            for (int i = 0; i < this.symbols.length; i++) {
                Symbol symbol = this.symbols[i];
                for (int j = 0; j < this.symbols.length; j++) {
                    Symbol symbol1 = this.symbols[j];
                    if (symbol.getRank() < symbol1.getRank()) {
                        temp = symbol;
                        symbol = symbol1;
                        symbol1 = temp;
                    } else if (symbol.getSymbol().compareTo(symbol1.getSymbol()) > 0) {
                        temp = symbol;
                        symbol = symbol1;
                        symbol1 = temp;
                    }
                }
            }
        }
    }
}
